#include "fileio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

// 日志文件路径
#define LOG_FILE "../log.log"

// 确保文件存在
int ensure_file_exists(const char* filename) {
    FILE* file = fopen(filename, "a");  // 以追加模式打开，如果不存在则创建
    if (file == NULL) {
        return 0;
    }
    fclose(file);
    return 1;
}

// 去除字符串首尾空白字符
void trim_whitespace(char* str) {
    if (str == NULL) return;
    
    char* start = str;
    while (isspace((unsigned char)*start)) start++;
    
    char* end = str + strlen(str) - 1;
    while (end > start && isspace((unsigned char)*end)) end--;
    
    *(end + 1) = '\0';
    
    if (start != str) {
        memmove(str, start, end - start + 2);
    }
}

// 检查是否为注释行
int is_comment_line(const char* line) {
    if (line == NULL) return 0;
    
    // 跳过前导空白字符
    while (isspace((unsigned char)*line)) line++;
    
    // 检查是否以 # 开头
    return (*line == '#');
}

// 解析学生数据行
int parse_student_line(const char* line, char* id, char* name, int* course_count, float* total_credits) {
    if (line == NULL || id == NULL || name == NULL) {
        return 0;
    }
    
    // 复制一行以便处理
    char buffer[256];
    strncpy(buffer, line, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';
    
    // 跳过注释行
    if (is_comment_line(buffer)) {
        return 0;
    }
    
    // 解析字段：学号,姓名,已选课程数,总学分
    char* token = strtok(buffer, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    strcpy(id, token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    strcpy(name, token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *course_count = atoi(token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *total_credits = atof(token);
    
    return 1;
}

// 解析课程数据行
int parse_course_line(const char* line, char* id, char* name, char* type, int* hours, float* credits, int* student_count, int* max_students) {
    if (line == NULL || id == NULL || name == NULL || type == NULL) {
        return 0;
    }
    
    // 复制一行以便处理
    char buffer[256];
    strncpy(buffer, line, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';
    
    // 跳过注释行
    if (is_comment_line(buffer)) {
        return 0;
    }
    
    // 解析字段：课程编号,课程名称,课程性质,授课学时,学分,已选人数,人数上限
    char* token = strtok(buffer, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    strcpy(id, token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    strcpy(name, token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    strcpy(type, token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *hours = atoi(token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *credits = atof(token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *student_count = atoi(token);
    
    token = strtok(NULL, ",");
    if (token == NULL) return 0;
    trim_whitespace(token);
    *max_students = atoi(token);
    
    return 1;
}

// 格式化学生数据行
int format_student_line(char* buffer, size_t size, Student* student) {
    if (buffer == NULL || student == NULL) {
        return 0;
    }
    
    int written = snprintf(buffer, size, "%s,%s,%d,%.1f",
                          student->id,
                          student->name,
                          student->course_count,
                          student->total_credits);
    
    return (written > 0 && written < size);
}

// 格式化课程数据行
int format_course_line(char* buffer, size_t size, Course* course) {
    if (buffer == NULL || course == NULL) {
        return 0;
    }
    
    int written = snprintf(buffer, size, "%s,%s,%s,%d,%.1f,%d,%d",
                          course->id,
                          course->name,
                          course->type,
                          course->hours,
                          course->credits,
                          course->student_count,
                          course->max_students);
    
    return (written > 0 && written < size);
}

// 从文件加载学生数据
int load_students_from_file(StudentList* list, const char* filename) {
    if (list == NULL || filename == NULL) {
        printf("❌ 参数错误: 学生链表或文件名为空\n");
        return -1;
    }
    
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        printf("⚠️  学生数据文件不存在: %s\n", filename);
        return 0;  // 文件不存在不是错误，返回0表示没有加载到数据
    }
    
    printf("📖 正在读取学生数据文件: %s\n", filename);
    
    char line[256];
    int loaded_count = 0;
    int line_number = 0;
    
    while (fgets(line, sizeof(line), file) != NULL) {
        line_number++;
        
        // 去除换行符
        line[strcspn(line, "\n")] = '\0';
        
        // 跳过空行和注释行
        if (strlen(line) == 0 || is_comment_line(line)) {
            continue;
        }
        
        // 解析学生数据
        char id[20], name[MAX_NAME_LEN];
        int course_count;
        float total_credits;
        
        if (parse_student_line(line, id, name, &course_count, &total_credits)) {
            // 添加学生到链表
            if (add_student(list, id, name)) {
                // 设置额外的学生信息
                Student* student = find_student(list, id);
                if (student != NULL) {
                    student->course_count = course_count;
                    student->total_credits = total_credits;
                }
                loaded_count++;
            } else {
                printf("⚠️  第%d行: 添加学生失败 - %s\n", line_number, line);
            }
        } else {
            printf("⚠️  第%d行: 格式错误 - %s\n", line_number, line);
        }
    }
    
    fclose(file);
    
    if (loaded_count > 0) {
        printf("✅ 成功加载 %d 名学生数据\n", loaded_count);
    } else {
        printf("ℹ️  未加载任何学生数据\n");
    }
    
    return loaded_count;
}

// 从文件加载课程数据
int load_courses_from_file(CourseList* list, const char* filename) {
    if (list == NULL || filename == NULL) {
        printf("❌ 参数错误: 课程链表或文件名为空\n");
        return -1;
    }
    
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        printf("⚠️  课程数据文件不存在: %s\n", filename);
        return 0;  // 文件不存在不是错误
    }
    
    printf("📖 正在读取课程数据文件: %s\n", filename);
    
    char line[256];
    int loaded_count = 0;
    int line_number = 0;
    
    while (fgets(line, sizeof(line), file) != NULL) {
        line_number++;
        
        // 去除换行符
        line[strcspn(line, "\n")] = '\0';
        
        // 跳过空行和注释行
        if (strlen(line) == 0 || is_comment_line(line)) {
            continue;
        }
        
        // 解析课程数据
        char id[20], name[MAX_COURSE_NAME_LEN], type[MAX_COURSE_TYPE_LEN];
        int hours, student_count, max_students;
        float credits;
        
        if (parse_course_line(line, id, name, type, &hours, &credits, &student_count, &max_students)) {
            // 添加课程到链表
            if (add_course(list, id, name, type, hours, credits, max_students)) {
                // 设置选课人数
                Course* course = find_course(list, id);
                if (course != NULL) {
                    course->student_count = student_count;
                }
                loaded_count++;
            } else {
                printf("⚠️  第%d行: 添加课程失败 - %s\n", line_number, line);
            }
        } else {
            printf("⚠️  第%d行: 格式错误 - %s\n", line_number, line);
        }
    }
    
    fclose(file);
    
    if (loaded_count > 0) {
        printf("✅ 成功加载 %d 门课程数据\n", loaded_count);
    } else {
        printf("ℹ️  未加载任何课程数据\n");
    }
    
    return loaded_count;
}

// 保存学生数据到文件
int save_students_to_file(StudentList* list, const char* filename) {
    if (list == NULL || filename == NULL) {
        printf("❌ 参数错误: 学生链表或文件名为空\n");
        return 0;
    }
    
    if (list->head == NULL) {
        printf("ℹ️  没有学生数据需要保存\n");
        return 1;  // 空链表也算成功
    }
    
    FILE* file = fopen(filename, "w");
    if (file == NULL) {
        printf("❌ 无法创建学生数据文件: %s\n", filename);
        return 0;
    }
    
    // 写入文件头注释
    fprintf(file, "# 学生数据文件\n");
    fprintf(file, "# 格式: 学号,姓名,已选课程数,总学分\n");
    
    StudentNode* current = list->head;
    int saved_count = 0;
    
    while (current != NULL) {
        char line[256];
        if (format_student_line(line, sizeof(line), &(current->student))) {
            fprintf(file, "%s\n", line);
            saved_count++;
        } else {
            printf("⚠️  格式化学生数据失败: %s\n", current->student.id);
        }
        current = current->next;
    }
    
    fclose(file);
    
    printf("✅ 成功保存 %d 名学生数据到 %s\n", saved_count, filename);
    return 1;
}

// 保存课程数据到文件
int save_courses_to_file(CourseList* list, const char* filename) {
    if (list == NULL || filename == NULL) {
        printf("❌ 参数错误: 课程链表或文件名为空\n");
        return 0;
    }
    
    if (list->head == NULL) {
        printf("ℹ️  没有课程数据需要保存\n");
        return 1;  // 空链表也算成功
    }
    
    FILE* file = fopen(filename, "w");
    if (file == NULL) {
        printf("❌ 无法创建课程数据文件: %s\n", filename);
        return 0;
    }
    
    // 写入文件头注释
    fprintf(file, "# 课程数据文件\n");
    fprintf(file, "# 格式: 课程编号,课程名称,课程性质,授课学时,学分,已选人数,人数上限\n");
    
    CourseNode* current = list->head;
    int saved_count = 0;
    
    while (current != NULL) {
        char line[256];
        if (format_course_line(line, sizeof(line), &(current->course))) {
            fprintf(file, "%s\n", line);
            saved_count++;
        } else {
            printf("⚠️  格式化课程数据失败: %s\n", current->course.id);
        }
        current = current->next;
    }
    
    fclose(file);
    
    printf("✅ 成功保存 %d 门课程数据到 %s\n", saved_count, filename);
    return 1;
}

// 加载初始数据
int load_initial_data(StudentList* student_list, CourseList* course_list) {
    if (student_list == NULL || course_list == NULL) {
        printf("❌ 参数错误: 学生链表或课程链表为空\n");
        return 0;
    }
    
    printf("📁 正在加载初始数据...\n");
    
    int student_count = load_students_from_file(student_list, "../student.txt");
    int course_count = load_courses_from_file(course_list, "../class.txt");
    
    if (student_count < 0 || course_count < 0) {
        printf("❌ 数据加载过程中发生错误\n");
        return 0;
    }
    
    printf("✅ 初始数据加载完成: %d名学生, %d门课程\n", 
           student_count > 0 ? student_count : 0, 
           course_count > 0 ? course_count : 0);
    
    return (student_count >= 0 && course_count >= 0);
}

// 保存所有数据
int save_all_data(StudentList* student_list, CourseList* course_list) {
    if (student_list == NULL || course_list == NULL) {
        printf("❌ 参数错误: 学生链表或课程链表为空\n");
        return 0;
    }
    
    printf("💾 正在保存所有数据...\n");
    
    int student_saved = save_students_to_file(student_list, "../student.txt");
    int course_saved = save_courses_to_file(course_list, "../class.txt");
    
    if (student_saved && course_saved) {
        printf("✅ 所有数据保存完成\n");
    } else {
        printf("❌ 数据保存失败\n");
    }
    
    return (student_saved && course_saved);
}

// 记录操作日志
void log_operation(const char* operation, const char* details) {
    if (operation == NULL) {
        return;
    }
    
    // 确保日志文件存在
    if (!ensure_file_exists(LOG_FILE)) {
        printf("⚠️  无法创建日志文件: %s\n", LOG_FILE);
        return;
    }
    
    FILE* file = fopen(LOG_FILE, "a");
    if (file == NULL) {
        printf("❌ 无法打开日志文件: %s\n", LOG_FILE);
        return;
    }
    
    // 获取当前时间
    time_t now = time(NULL);
    struct tm* timeinfo = localtime(&now);
    char timestamp[20];
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", timeinfo);
    
    // 写入日志
    if (details != NULL) {
        fprintf(file, "[%s] %s: %s\n", timestamp, operation, details);
    } else {
        fprintf(file, "[%s] %s\n", timestamp, operation);
    }
    
    fclose(file);
}

// 创建示例数据文件（可选功能）
int create_sample_data_files() {
    printf("📝 正在创建示例数据文件...\n");
    
    // 创建学生数据文件
    FILE* student_file = fopen("../student.txt", "w");
    if (student_file == NULL) {
        printf("❌ 无法创建学生示例数据文件\n");
        return 0;
    }
    
    fprintf(student_file, "# 学生数据文件\n");
    fprintf(student_file, "# 格式: 学号,姓名,已选课程数,总学分\n");
    fprintf(student_file, "20230001,张三,0,0.0\n");
    fprintf(student_file, "20230002,李四,0,0.0\n");
    fprintf(student_file, "20230003,王五,0,0.0\n");
    fprintf(student_file, "20230004,赵六,0,0.0\n");
    fprintf(student_file, "20230005,钱七,0,0.0\n");
    fclose(student_file);
    
    // 创建课程数据文件
    FILE* course_file = fopen("../class.txt", "w");
    if (course_file == NULL) {
        printf("❌ 无法创建课程示例数据文件\n");
        return 0;
    }
    
    fprintf(course_file, "# 课程数据文件\n");
    fprintf(course_file, "# 格式: 课程编号,课程名称,课程性质,授课学时,学分,已选人数,人数上限\n");
    fprintf(course_file, "CS001,C语言程序设计,必修,64,4.0,0,50\n");
    fprintf(course_file, "CS002,数据结构,必修,72,4.5,0,45\n");
    fprintf(course_file, "MA001,高等数学,必修,80,5.0,0,60\n");
    fprintf(course_file, "EN001,大学英语,必修,64,4.0,0,55\n");
    fprintf(course_file, "PH001,大学物理,必修,72,4.5,0,40\n");
    fclose(course_file);
    
    // 创建空日志文件
    FILE* log_file = fopen(LOG_FILE, "w");
    if (log_file != NULL) {
        fprintf(log_file, "# 系统操作日志\n");
        fprintf(log_file, "# 格式: [时间] 操作类型: 详细信息\n");
        fclose(log_file);
    }
    
    printf("✅ 示例数据文件创建完成:\n");
    printf("   - student.txt (学生数据)\n");
    printf("   - class.txt (课程数据)\n");
    printf("   - log.log (操作日志)\n");
    
    return 1;
}
